# -*- coding: utf-8 -*-

 ###############################################
 ##                                             ##
 ##  Model (Reportes)                            ##
 ##                                              ##
 ##                                              ##
 ##  for Basiq Series                            ##
 ##  by Críptidos Digitales                      ##
 ##  GPL (c)2008                                 ##
  ##                                             ##
    ###############################################


import sys
from decimal import Decimal as dec
from sqlalchemy import desc, or_
from sqlalchemy.sql import func

#~ import man
# from man import Acepcion, Atributo, Contacto, Direccion, Documento, Entidad, Operacion, PartidaDocumento, Proceso, Producto, Rol
#~ from man import *

#~ from mainModel import *

from baseModel import *






def getCustomers():
    typeCustomer = getAttribute(grupo='tipoRol', nombre='cliente')
    query("""SELECT * FROM roles JOIN entidades USING (id) WHERE tipo_id=%s ORDER BY nombre""" % typeCustomer['id'])
    customers = fetchAll()

    global __customersCount
    __customersCount = len(customers)

    return customers

def getDefaultCustomer():
    customer = getFullRol(id=int(getAttribute(grupo=u'cliente', nombre=u'default')['valor']))
    #~ customer['addresses'] = direcciones(rol_id=customer['id'])
    return customer


def getProductCount():
    query("""SELECT count(*) FROM productos""")
    return fetchOne()['count']


def getSalesCount():
    query("""SELECT count(*) FROM procesos WHERE tipo='Venta'""")
    return fetchOne()['count']


def getDefaultSalesDocumentType():
    documentType = getAttribute(grupo=u'tipoDocumentoVenta', nombre=u'default')
    return documentType


def getTiposDocumento():
    registros = getAttributes(grupo=u'tipoDocumento')
    return registros











def payables():
    query("""SELECT * FROM operaciones WHERE operacion_tipo='pago' AND status='por pagar' ORDER BY fecha2 DESC""")
    data = fetchAll()
    return data

    registros = man.session().query(Operacion).filter(Operacion.tipo==u"pago").filter(Operacion.status==u'por pagar').order_by(Operacion.fecha2.desc()).all()
    return registros



def payablesCount():
    query("""SELECT count(*) FROM operaciones WHERE operacion_tipo='pago' AND status='por pagar' """)
    data = fetchOne()
    return data['count']

    return man.session().query(func.count(Operacion.operacion_id)).filter(Operacion.tipo==u"pago").filter(Operacion.status==u'por pagar').one()[0]


def receivables():
    query("""SELECT * FROM operaciones WHERE operacion_tipo='cobro' AND status='por cobrar' ORDER BY fecha2 DESC""")
    data = fetchAll()
    return data

    registros = man.session().query(Operacion).filter(Operacion.tipo==u"cobro").filter(Operacion.status==u'por cobrar').order_by(Operacion.fecha2.desc()).all()

    return registros



def receivablesCount():
    query("""SELECT count(*) FROM operaciones WHERE operacion_tipo='cobro' AND status='por cobrar' """)
    data = fetchOne()
    return data['count']


    return man.session().query(func.count(Operacion.operacion_id)).filter(Operacion.operacion_tipo==u"cobro").filter(Operacion.status==u'por cobrar').one()[0]






def acepcionExiste(**filtros):
    try:
        if 'codigo' in filtros.keys():
            registro = man.session().query(Acepcion).filter(Acepcion.codigo==unicode(filtros['codigo'])).filter(Acepcion.rol_id==filtros['rol_id']).filter(Acepcion.status==u'actual').one()
        else:
            registro = man.session().query(Acepcion).filter(Acepcion.producto_id==filtros['producto_id']).filter(Acepcion.rol_id==filtros['rol_id']).filter(Acepcion.status==u'actual').one()
        return registro
    except:
        return None


def agrega(data):
    # proceso = dameProceso({'id':damePedido({'id':data['pedido']}).proceso_id})
    # if not proceso:
    proceso = Proceso(data['proceso']['tipo'], data['proceso']['fecha'], data['proceso']['status'])
    man.session().add(proceso)
    man.session().flush()

    documento = Documento(proceso.proceso_id, data['tipo'], data['folio'], data['fecha'], data['entidad_id'], data['subtotal'], data['descuento'], data['impuesto'], data['total'], data['status'])
    proceso.documentos.append(documento)
    man.session().add(documento)
    man.session().flush()

    for partida in data['partidas']:
        partida = PartidaDocumento(documento.documento_id, partida['producto_id'], partida['cantidad'], partida['costo'], partida['precio'], partida['descuento'], partida['impuesto'], partida['status'])
        documento.partidas.append(partida)
        man.session().add(partida)
    man.session().flush()

    operacion = Operacion("inventarios", data['fecha'], data['fecha'], documento.documento_id, data['total'], data['status'])
    man.session().add(operacion)

    operacion = Operacion("caja", data['fecha'], data['fecha'], documento.documento_id, data['total'], data['status'])
    man.session().add(operacion)

    operacion = Operacion("por cobrar", data['fecha'], data['fecha'], documento.documento_id, data['total'], u"pagada")
    man.session().add(operacion)

    consolidaSalidas(documento.partidas)



    modificaFolio(data['folio'], documento.tipo)

    man.session().commit()
    return True


def consolidaSalidas(partidas):
    for registro in partidas:
        if registro.producto.actual:
            registro.producto.actual -= registro.cantidad
        else:
            registro.producto.actual = registro.cantidad
    man.session().flush()


def dameAcepcion(**filtros):
    try:
        if not filtros.has_key('status'):
            filtros['status'] = u'actual'
        registro = man.session().query(Acepcion).filter_by(**filtros).one()
    except:
        print sys.exc_info()
        print filtros
    return registro


def dameAcepciones(**filtros):
    registros = []
    if filtros.has_key('rol_id'):
        if filtros.has_key('clasificacion'):
            if filtros.has_key('nombre'):
                registros = man.session().query(Acepcion).filter(Acepcion.status==u'actual').filter(Acepcion.nombre.like("%s%%" % filtros['nombre'])).filter(Acepcion.rol_id==filtros['rol_id']).join(Producto).filter(Producto.clasificacion==filtros['clasificacion']).order_by(Acepcion.nombre).all()
            elif filtros.has_key('codigo'):
                registros = man.session().query(Acepcion).filter(Acepcion.status==u'actual').filter(Acepcion.codigo.like("%s%%" % filtros['codigo'])).filter(Acepcion.rol_id==filtros['rol_id']).join(Producto).filter(Producto.clasificacion==filtros['clasificacion']).order_by(Acepcion.codigo).all()
        else:
            if filtros.has_key('nombre'):
                registros = man.session().query(Acepcion).filter(Acepcion.status==u'actual').filter(Acepcion.nombre.like("%s%%" % filtros['nombre'])).filter(Acepcion.rol_id==filtros['rol_id']).order_by(Acepcion.nombre).all()
            elif filtros.has_key('codigo'):
                registros = man.session().query(Acepcion).filter(Acepcion.status==u'actual').filter(Acepcion.codigo.like("%s%%" % filtros['codigo'])).filter(Acepcion.rol_id==filtros['rol_id']).order_by(Acepcion.codigo).all()
    else:
        if filtros.has_key('clasificacion'):
            if filtros.has_key('nombre'):
                registros = man.session().query(Acepcion).filter(Acepcion.status==u'actual').filter(Acepcion.nombre.like("%s%%" % filtros['nombre'])).join(Producto).filter(Producto.clasificacion==filtros['clasificacion']).order_by(Acepcion.nombre).all()
            elif filtros.has_key('codigo'):
                registros = man.session().query(Acepcion).filter(Acepcion.status==u'actual').filter(Acepcion.codigo.like("%s%%" % filtros['codigo'])).join(Producto).filter(Producto.clasificacion==filtros['clasificacion']).order_by(Acepcion.codigo).all()
        else:
            if filtros.has_key('nombre'):
                registros = man.session().query(Acepcion).filter(Acepcion.status==u'actual').filter(Acepcion.nombre.like("%s%%" % filtros['nombre'])).order_by(Acepcion.nombre).all()
            elif filtros.has_key('codigo'):
                registros = man.session().query(Acepcion).filter(Acepcion.status==u'actual').filter(Acepcion.codigo.like("%s%%" % filtros['codigo'])).order_by(Acepcion.codigo).all()
    return registros


# def dameAtributo(**filtros):
    # registro = man.session().query(Atributo).filter(Atributo.propietario==unicode(filtros['propietario'])).filter(Atributo.nombre==unicode(filtros['nombre'])).one()
    # return registro


def dameCliente(**filtros):
    if 'id' in filtros.keys():
        registro = man.session().query(Rol).filter(Rol.id==filtros['id']).one()
    elif 'nombre' in filtros.keys():
        registro = man.session().query(Rol).join(Rol.entidad).filter(Entidad.nombre==unicode(filtros['nombre'])).one()
    return registro


# def dameDocumento(**filtros):
    # if 'id' in filtros.keys():
        # registro = man.session().query(Documento).filter(Documento.id==filtros['id']).one()
    # return registro


def dameDocumentos(**filtros):
    registros = man.session().query(Documento).filter_by(**filtros).order_by(Documento.fecha).all()
    return registros


def dameFolio(tipoDocumento):
    if tipoDocumento == u'Factura'.capitalize():
        folio = int(man.session().query(Atributo.valor).filter(Atributo.propietario==u'ventas').filter(Atributo.nombre==u'ultimoFolioFiscal').one()[0])
    elif tipoDocumento == u'Remisión'.capitalize():
        folio = int(man.session().query(Atributo.valor).filter(Atributo.propietario==u'ventas').filter(Atributo.nombre==u'ultimoFolioControl').one()[0])
    folio += 1
    return folio


def dameOperaciones(**filtros):
    registros = man.session().query(Operacion).filter(Operacion.documento_id==filtros['documento_id']).all()
    return registros


def damePartidas(**filtros):
    if 'producto_id' in filtros.keys():
        if 'tipo' in filtros.keys():
            registros = man.session().query(PartidaDocumento).filter(PartidaDocumento.producto_id==filtros['producto_id']).join(Documento).filter(Documento.tipo.in_(filtros['tipo'])).order_by(Documento.fecha.desc()).all()
        else:
            # registros = man.session().query(PartidaDocumento).filter(PartidaDocumento.producto_id==filtros['producto_id']).order_by(PartidaDocumento.id.desc()).all()
            registros = man.session().query(PartidaDocumento).filter(PartidaDocumento.producto_id==filtros['producto_id']).join(Documento).order_by(Documento.fecha.desc()).all()
    return registros


def dameProceso(**filtros):
    if 'id' in filtros.keys():
        registro = man.session().query(Proceso).filter(Proceso.proceso_id==filtros['id']).one()
    return registro


def producto(**filtros):
    registro = man.session().query(Producto).filter(Producto.id==filtros['id']).one()
    return registro



# def dameRoles(**filtros):
    # if 'nombre' in filtros.keys():
        # if 'like' in filtros['nombre']:
            # registros = man.session().query(Rol).filter(Rol.tipo==filtros['tipo']).join(Entidad).filter(Entidad.nombre.like("%s%%" % filtros['nombre'].replace('like ', ''))).order_by(Entidad.nombre).all()
    # else:
        # registros = man.session().query(Rol).filter_by(**filtros).join(Entidad).order_by(Entidad.nombre).all()
    # return registros


def dameVentas(**filtros):
    fecha = filtros['inicio']
    totales = []

    while fecha <= filtros['termino']:
        ventas = dameVentasPorFecha(fecha)
        total = dec("0.00")
        for venta in ventas:
            total += venta.total
        totales.append({'fecha':fecha, 'total':total})
        fecha = fecha.addDays(1)
    return totales


def dameVentasPorFecha(fecha):
    registros = man.session().query(Documento).join(Proceso).filter(Proceso.tipo==u'Venta').filter(Documento.fecha==fecha.toPyDate()).filter(Documento.tipo!=u'Pedido').all()
    return registros


def modificaActual(**kwds):
    product = producto(id=kwds['producto_id'])
    product.actual = kwds['actual']
    man.session().commit()


